home *** CD-ROM | disk | FTP | other *** search
/ Aminet 22 / Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso / Aminet / util / blank / BeyondTheDark.lha / BeyondTheDark / Developer / Source / Skeleton / Skeleton.c < prev   
C/C++ Source or Header  |  1997-10-14  |  12KB  |  428 lines

  1. /* 
  2.    Skeleton Library for BTD 
  3.    Comments by Markus Illenseer 
  4.   
  5.    This source tries to give valuable hints to write a Modul
  6.    for BTD. As you will see, this is quite easy, even if it is
  7.    the first time you write a library.
  8.  
  9.    This Skeleton Blanker draws random dots in 4 colors for a certain time,
  10.    then cleans up the screen and starts again. Nothing sophisticated.
  11.  
  12.    Also do refer to BTD.h for global defines and structures.
  13.  
  14. */
  15.  
  16. #include <exec/memory.h>
  17. #include <exec/execbase.h>
  18. #include <graphics/gfxbase.h>
  19. #include <intuition/intuitionbase.h>
  20. #include <libraries/iffparse.h>
  21. #include <utility/tagitem.h>
  22.  
  23. #include <clib/macros.h>
  24.  
  25. #define __USE_SYSBASE 42
  26.  
  27. #include <proto/exec.h>
  28. #include <proto/graphics.h>
  29. #include <proto/intuition.h>
  30. #include <proto/utility.h>
  31.  
  32. #include <BTD.h>
  33.  
  34. struct IntuitionBase *IntuitionBase;
  35. struct GfxBase *GfxBase;
  36. struct Library *UtilityBase;
  37.  
  38. /* 
  39.    Don't open any libraries by yourself. This _must_ be done
  40.    in the assembler part of the library. 
  41.  
  42.    Be sure your library is re-entrant. Means, one must be able to
  43.    open the library several times at once. So don't use global 
  44.    variables other than static (unchangable) ones. Use ModulStruct
  45.    for that purpose.
  46. */
  47.  
  48. /* #define DEBUG YES */
  49.  
  50. /*
  51.    Remove above comment braces (uncomment) to use the Debug-Output.
  52.    Use Terminal connected to serial line, or use sushi to
  53.    redirect the output. Be carefull with modems!
  54.    Remember to add the Debug.lib in the Makefile.
  55.  
  56.    DEBUG_PRINT prints only text.
  57.    DEBUG_PRINTF prints any text and one (!) variable of any kind
  58.  
  59.    This is the only easy way to debug libaries! The SDB or other
  60.    debuggers have some problems with libraires, at least as source
  61.    level debuggers.
  62.  
  63. */
  64.  
  65. #ifdef DEBUG 
  66.  
  67. void KPrintF(char *,...);
  68.  
  69. #define DEBUG_PRINTF(a,b)  KPrintF(a,b);
  70. #define DEBUG_PRINT(a)     KPrintF(a)
  71. #else
  72. #define DEBUG_PRINTF(a,b)
  73. #define DEBUG_PRINT(a)
  74. #endif
  75.  
  76. /* Now we define the Macros for easy access to the Tag-Entries */
  77.  
  78. #define DTAG(o) (BTD_Client+(o))
  79.  
  80. #define ST_Seconds DTAG(0)
  81.  
  82. /* How much time we give, until the screen is cleaned up again */
  83.  
  84. #define DEF_SECONDS 5L
  85. #define MAX_SECONDS 60L
  86.  
  87. /*
  88.    This structure defines the INTEGER parameters, which the user
  89.    can supply.  Skeleton requires only the seconds until it will
  90.    clean up the screen.  For other type of paramters, refer to BTD.h 
  91. */
  92.  
  93. struct BTDInteger SkeletonIntParams[] =
  94.  {
  95.   ST_Seconds,"Seconds",BTDPT_INTEGER,DEF_SECONDS,1L,MAX_SECONDS,TRUE,
  96.  };
  97.  
  98. /*
  99.    This Taglist is send to the Preference-Programm which will
  100.    open a window with the hereby supplied gadgets.  Skeleton needs
  101.    only the one Integer-Slider 
  102. */
  103.  
  104. struct BTDNode *SkeletonParams[] = 
  105.  {
  106.   &SkeletonIntParams[0].BI_Node,
  107.   NULL
  108.  };
  109.  
  110. /*
  111.    This structure sends some info about the modul to the Preference-
  112.    Programm.  MAKE_ID is required for MUI, and will make it possible
  113.    to save the position of this specific preference window.
  114.    First string defines the NAME of the blanker, possibly something
  115.    different than the probaly cryptic filename of the library.
  116.    Second string contains a short description about the blanker.  A \n will
  117.    split up the string into a new line.
  118.    Third string should contain your Name and a Copyright message if
  119.    necessary.
  120.  
  121.    The Version Number is not defined here, but in the Assembler-Part
  122.    of the source!
  123.  
  124.    Last Tag is the Node-Info, which will request the user for parameters
  125.    with above given List in BTDNode.
  126. */
  127.  
  128. struct BTDInfo SkeletonInfo =
  129.  {
  130.   BTDI_Revision,MAKE_ID('S','K','E','L'),
  131.   "Skeleton Blanker","Skeleton is intended for programmers\n among you peoples!\nJust a simple and boring blanker modul","Markus Illenseer 1994",
  132.   SkeletonParams
  133.  };
  134.  
  135.  
  136. /*
  137.    This is our 'global' structure for the skeleton blanker. I refer to
  138.    it as ModulStruct.
  139.    Remember that this is the only way to hold global data for each 
  140.    invoked modul out of this library. The Skeleton Blanker will only 
  141.    hold info about the supplied second-parameter and about the time when 
  142.    the screen was cleaned up the last time. And of course it will hold 
  143.    the BTDDrawInfo, which contains lot of required info, eg. RastPort.
  144.  
  145.    If you require anything sophisticated like ImageData, have a look into
  146.    the other supplied modules. 
  147. */
  148.  
  149. struct SkeletonStruct
  150.  {
  151.   struct BTDDrawInfo *BTDDrawInfo;
  152.   LONG Seconds;
  153.   LONG Time;
  154.   LONG RandN,RandF,RandI;
  155.  };
  156.  
  157. /* library stuff */
  158.  
  159. char MyBlankerName[] = "skeleton.btd";
  160. char MyBlankerID[]   = "Skeleton Blanker V" VERSION "." REVISION " for BTD";
  161.  
  162. LONG MyBlankerLibInit(void)
  163.  
  164. {
  165.  if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))
  166.   {
  167.    if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))
  168.     {
  169.      if (UtilityBase=OpenLibrary("utility.library",37L)) return TRUE;
  170.  
  171.      CloseLibrary (&IntuitionBase->LibNode);
  172.     }
  173.    CloseLibrary (&GfxBase->LibNode);
  174.   }
  175.  return FALSE;
  176. }
  177.  
  178. void MyBlankerLibFree(void)
  179.  
  180. {
  181.  CloseLibrary (UtilityBase);
  182.  CloseLibrary (&IntuitionBase->LibNode);
  183.  CloseLibrary (&GfxBase->LibNode);
  184. }
  185.  
  186. /* implementation of library functions */
  187.  
  188. struct BTDInfo *QueryMyBlanker(void)
  189.  
  190. {
  191.  return &SkeletonInfo;
  192. }
  193.  
  194. /*
  195.    The next two functions are some sophisticated Randomnizers
  196.    which are based upon (mathematic) statistic defined true 
  197.    Randomnizers. All they need is a seed, afterwards they will use
  198.    the current time as a base for future randoms. 
  199.  
  200.    Normally we would have some global variabled for RandN, RandF and
  201.    RandI, but as we need to be re-entrant, we need to store this info
  202.    in the ModulStruct above. 
  203. */
  204.  
  205. void __regargs InitRandom(struct SkeletonStruct *Skel,ULONG Instance)
  206.  
  207. {
  208.  ULONG Time[2];
  209.  
  210.  CurrentTime (&Time[0],&Time[1]);
  211.  Skel->RandN=(LONG)Time[0];
  212.  
  213.  if (Time[1]<1024L) Time[1]|=1;
  214.  else Time[1]>>=10;
  215.  Time[1]^=Instance;
  216.  
  217.  Skel->RandF=4*Time[1]+1;
  218.  Skel->RandI=2*Time[1]+1;
  219. }
  220.  
  221. WORD __regargs Random(struct SkeletonStruct *Skel,WORD Max)
  222.  
  223. {
  224.  Skel->RandN=Skel->RandF*Skel->RandN+Skel->RandI;
  225.  if (Skel->RandN<0L) Skel->RandN=-Skel->RandN;
  226.  
  227.  return (WORD)(Skel->RandN%Max);
  228. }
  229.  
  230. /* 
  231.    This is the first procedure every modul requires. It will initialize
  232.    the modul, eat required memory, set colors, whatever. This function
  233.    should be as short as possible. No heavy calculations belong here 
  234.  
  235.    struct ModulStruct InitModul(struct TagItem *TagList)
  236.  
  237.    Input: TagList is supplied from BTD-CX, the server, and will send
  238.           you all the parameters you requested from the user in above
  239.           structure BTDInfo. 
  240.  
  241.    Output: Fully initialized ModulStruct for further use, is returned
  242.            to the server, who will then invoke AnimModul() with this
  243.            structure. 
  244. */
  245.  
  246. struct SkeletonStruct *InitMyBlanker(struct TagItem *TagList)
  247.  
  248. {
  249.  struct SkeletonStruct *SkelStruct;
  250.  struct BTDDrawInfo *BTDDrawInfo;
  251.  ULONG *Error,Dummy,Instance,Index;
  252.  
  253. DEBUG_PRINT("Skeleton: Initialize Modul\n");
  254.  
  255.  /* Find the Entry for the BTDDrawInfo (see BTD.h) and make local copy */
  256.  
  257.  if ((BTDDrawInfo=(struct BTDDrawInfo *)
  258.                    GetTagData(BTD_DrawInfo,NULL,TagList))==NULL) return NULL;
  259.  
  260. /* 
  261.    Get us the Dummy, which will contain Error-Messages if we fail to
  262.    initialize our Modul. The server then knows we failed and will display
  263.    a black part on the screen 
  264. */
  265.  
  266.  Error=(LONG *)GetTagData(BTD_Error,(ULONG)&Dummy,TagList);
  267.  
  268. /*
  269.    Allocate the required MEM for the SkeletonStruct, on error report
  270.    a Memory-error to the server and return home 
  271. */
  272.  
  273.  if ((SkelStruct=AllocVec(sizeof(struct SkeletonStruct),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  274.   {
  275.    *Error=BTDERR_Memory;
  276.    return NULL;
  277.   }
  278.  
  279. /*
  280.    copy local BTDDrawInfo into global structure for future use in 
  281.    AnimModul() 
  282. */
  283.  
  284.  SkelStruct->BTDDrawInfo=BTDDrawInfo;
  285.  
  286. /*
  287.   The Instance is sort of OpenCounter and is often used to initialize
  288.   a Randomnizer, so that same modules won't use same random-seed 
  289. */
  290.  
  291.  Instance=GetTagData(BTD_Instance,0L,TagList);
  292.  
  293.  InitRandom(SkelStruct,Instance);
  294.  
  295. /* Get us the user-supplied parameter SECONDS */
  296.  
  297.  SkelStruct->Seconds=GetTagData(ST_Seconds,DEF_SECONDS,TagList);
  298.  
  299.  
  300. /* 
  301.   Set an initial value, not really required to do so, as we allocated
  302.   the SkelStruct with MEMF_CLEAR flag 
  303. */
  304.  
  305.  SkelStruct->Time=0L;
  306.  
  307.  
  308. /* 
  309.   Now set our requested colors to any RGB-Tripel, you MUST use
  310.   this array, otherwise you won't get your colors, but anything
  311.   else. Can yield to a Guru if you do that! 
  312. */
  313.  
  314.  for(Index=0; Index<4; Index++)
  315.   {
  316.    BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=Random(SkelStruct,255);
  317.    BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=Random(SkelStruct,255);
  318.    BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=Random(SkelStruct,255);
  319.    BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  320.   }
  321.  
  322. /* Everything's done. Return the structure for future use */
  323.  
  324.  return SkelStruct;
  325. }
  326.  
  327. /* This is the second procedure required for every modul. It should
  328.    do anything required to free resources, free mem and so on. 
  329.  
  330.    void EndMyBlanker(struct ModulStruct *ModulStruct)
  331.  
  332.    Input: ModulStruct supplied from server BTD-CX
  333.    Output: None. Should all be freed up */
  334.  
  335. void EndMyBlanker(struct SkeletonStruct *SkelStruct)
  336.  
  337. {
  338. DEBUG_PRINT("Skeleton: about to finish Modul\n");
  339.  FreeVec (SkelStruct);
  340. }
  341.  
  342. /* Third procedure required for a modul. This one is called by the
  343.    server every once in a second. You are not allowed to do anything
  344.    which would yield into a FOREVER-Loop or do anything like a busy-loop
  345.    or something unstoppable. 
  346.  
  347.    If you need to do a loop from TOP to BOTTOM (TOP+HEIGHT), add a counter
  348.    in ModulStruct: ypos. Best would even to add xpos also, if required.
  349.    
  350.    These restictions are all due to the fact, that the user want's his
  351.    screen back as fast as possible!
  352.  
  353.    void AnimMyBlanker(struct ModulStruct *ModulStruct)
  354.  
  355.    Input: ModulStruct supplied from server BTD-CX.
  356.    OutPut: None.
  357.  
  358. */
  359.  
  360. void AnimMyBlanker(struct SkeletonStruct *SkelStruct)
  361.  
  362. {
  363.  ULONG Seconds,Micros;
  364.  
  365.  /* Hum, below DEBUG_PRINT not that usefull. Remove it, or replace
  366.     it with anything you need to check */
  367.  
  368. DEBUG_PRINT("Skeleton: Animate\n");
  369.  
  370. /* Get us the current time. */
  371.  
  372.  CurrentTime (&Seconds,&Micros);
  373.  
  374.  if (Seconds>=SkelStruct->Time)
  375.   {
  376.  
  377. /* Wait for that the pointer is at the top of the screen */
  378.    WaitTOF();
  379.  
  380. /* Calculate next timeslide */
  381.  
  382.    SkelStruct->Time=Seconds+SkelStruct->Seconds;
  383.    
  384. /* Set Background color, attention, have a look at the color! */
  385.  
  386.    SetAPen(SkelStruct->BTDDrawInfo->BDI_RPort,BTD_BgPen);
  387.  
  388. /* Fill our part of the screen with background color */
  389.  
  390.    RectFill (SkelStruct->BTDDrawInfo->BDI_RPort,
  391.              SkelStruct->BTDDrawInfo->BDI_Left,
  392.              SkelStruct->BTDDrawInfo->BDI_Top,
  393.              SkelStruct->BTDDrawInfo->BDI_Left+SkelStruct->BTDDrawInfo->BDI_Width-1,
  394.              SkelStruct->BTDDrawInfo->BDI_Top+SkelStruct->BTDDrawInfo->BDI_Height-1);
  395.   }
  396.  
  397. /* Now let's do the magic Animation of Skeleton */
  398.  
  399. /* Choose Random Color and set Pen accordingly */
  400.  
  401.   SetAPen (SkelStruct->BTDDrawInfo->BDI_RPort,
  402.            SkelStruct->BTDDrawInfo->BDI_Pens[Random(SkelStruct,4)]);
  403.  
  404. /* 
  405.   You can speed up the process, if you store LEFT, TOP, HEIGHT. WIDTH
  406.   in ModulStruct directly, rather than in a pointer to BTDDrawInfo 
  407. */
  408.  
  409.   WritePixel (SkelStruct->BTDDrawInfo->BDI_RPort,
  410.               SkelStruct->BTDDrawInfo->BDI_Left+Random(SkelStruct,SkelStruct->BTDDrawInfo->BDI_Width),
  411.               SkelStruct->BTDDrawInfo->BDI_Top+Random(SkelStruct,SkelStruct->BTDDrawInfo->BDI_Height));
  412. }
  413.  
  414. ULONG PenCountMyBlanker(struct TagItem *TagList)
  415.  
  416. {
  417.  
  418. /*
  419.    We request to use 4 colors, we _will_ get them! 
  420.    We would even get 324 colors, if there is a screenmode with that
  421.    many colors, and the servers gives us that many. 
  422.    If the servers sees that we need more colors as he can provide with
  423.    his used screenmode, he won't use our modul 
  424. */
  425.  
  426.  return 4L;
  427. }
  428.